home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / docs / mags / ARTv1i1A.lha / smake.lha / rcs-smakefile.doc next >
Encoding:
Text File  |  1995-03-16  |  10.0 KB  |  257 lines

  1. USE OF MAKEFILE IN PROJECT MANAGEMENT
  2.  
  3.  
  4. Preamble
  5.  
  6. A surprising number of programmers are not aware of the various tricks
  7. that can be used to simplify the compilation of their programs. A Makefile
  8. can play a big part in this process, but many times it is sadly neglected
  9. or sometimes not in fact used at all.
  10.  
  11. Even a larger number of programmers have their source files in varying
  12. degrees of chaos, with only random copies, if any, of the older versions
  13. for reference or backup.
  14.  
  15. Most programmers have at one point or another come across the situation
  16. where an archive of their source code would have saved a lot of trouble.
  17. You might have accidentally destroyed a source file or even the whole
  18. source tree of your latest program, or maybe introduced a bug that you
  19. just can not track down and fix, but which you know wasn't in the last
  20. week's version.
  21.  
  22. Revision control is the answer to these situations. In this article I will
  23. try to explain how to use both Makefiles and revision control systems to
  24. help development of your projects.
  25.  
  26.  
  27. The environment
  28.  
  29. I developed the techniques described in this article over a couple of
  30. programming projects. The development platform used is an Amiga 3000, and
  31. the software consists of the SAS/C 6.51 compiler, Heinz Wrobel's port of
  32. the RCS software (HWGRCS) and Many features of the SMakefile used as the
  33. project base are unique to SAS/C's SMake, and it very probably won't work
  34. without some changes in other environments. The ideas, however, are
  35. global, and this article should be able to give you some hints even if you
  36. use another compiler.
  37.  
  38.  
  39. Makefile
  40.  
  41. Make is a tool that operates on files using a set of rules as the guide to
  42. what to do to each of them. These rules are listed in a file called the
  43. Makefile. In essence, a Make rule consists of a target file, a list of the
  44. source files on which it depends, and the instructions on how to create
  45. the target file from the source files. A simple example might look like
  46. this:
  47.  
  48. foobar:    foo.o bar.o
  49.     slink foo.o bar.o to foobar
  50.  
  51. This is one Make rule. It says "to create 'foobar' from 'foo.o' and
  52. 'bar.o', run the command 'slink foo.o bar.o to foobar'". Make will then
  53. look for the source files and determine if 'foobar' needs to be updated or
  54. not. Make also has some built in intelligence. For example, it knows that
  55. if it does not find a file with the name ending in '.o', it should look
  56. for the corresponding file ending in '.c', and compile that file first.
  57. Thus, 'foobar' gets updated if either of the two source files 'foo.c' or
  58. 'bar.c' has been changed since the last update, and only the parts that
  59. need to be compiled will be.
  60.  
  61.  
  62. RCS
  63.  
  64. RCS, short for Revision Control System, is a software package used to
  65. manage multiple versions (revisions) of files. It facilitates the storing,
  66. retrieval and merging of of versions of the same file, letting the user
  67. log the changes. It is useful as the storage system of various types of
  68. files that are revised frequently. Program source code is only one,
  69. although an obvious example.
  70.  
  71. RCS can also be used in an environment where many people use the same
  72. source tree, letting only one person have a modifiable copy of a file,
  73. thus limiting the possibilities of two persons making changes at the same
  74. time. This might sound complicated, but in effect RCS can be very simple
  75. to use.
  76.  
  77. The basic use of RCS is based around two commands, "ci" (check in) and
  78. "co" (check out). These commands let you store a file to the RCS database,
  79. and get a copy of that file out for viewing or modifications. You could,
  80. for example use "ci -r2.13 niftyprog.c" to store the source of version
  81. 2.13 of your utility program. While RCS is usable manually, it does get
  82. somewhat tiresome as the project size grows. There is also a problem with
  83. keeping RCS revision numbers and your own program version number agreeing,
  84. unless you have some automated help to handle that.
  85.  
  86. Here's where a good Makefile comes in handy. A Makefile can automatically
  87. increment the revision number after each recompile, and when you are happy
  88. with the program, you can archive the current revision with the correct
  89. number with a single command.
  90.  
  91.  
  92. The SMakefile
  93.  
  94. There is no single solution to the problem of creating a Makefile that can
  95. handle not only the building of a project, but also the archival of it. I
  96. will list here a stripped down version of the template SMakefile I build
  97. my projects on. The whole version, complete with comments, is included as
  98. a separate file. In the following, the lines are numbered for reference
  99. later in the article.
  100.  
  101. 1.    # SMakefile for SAS/C
  102. 2.    
  103. 3.    # Project files
  104. 4.    
  105. 5.    PROG=        xxx
  106. 6.    SRCS=        $(PROG).c
  107. 7.    OBJS=        $(PROG).o
  108. 8.    INCS=        $(PROG).h
  109. 9.    MISC=        SMakefile
  110. 10.    LIBS=
  111. 11.    DEBUGLIBS=    LIB:debug.lib
  112. 12.    
  113. 13.    # Files to delete on "smake clean"
  114. 14.    
  115. 15.    JUNK=        \#?.(o|map|lnk|gst) SCOPTIONS
  116. 16.    
  117. 17.    # Build options
  118. 18.    
  119. 19.    CFLAGS=        DEBUG=LINE OPTIMIZE NOSTACKCHECK
  120. 20.    DCFLAGS=    DEBUG=SYMBOLFLUSH NOOPTIMIZE DEF=DEBUG
  121. 21.    LDFLAGS=    STRIPDEBUG
  122. 22.    HOOKFLAGS=    NOSTACKCHECK NOSTACKEXTEND
  123. 23.    
  124. 24.    # Compiler defaults
  125. 25.    
  126. 26.    SCOPTIONS=    
  127. 27.    
  128. 28.    # Programs used
  129. 29.    
  130. 30.    MAKE=        smake
  131. 31.    VER=        ver
  132. 32.    CP=        copy
  133. 33.    CAT=        type
  134. 34.    RM=        delete quiet
  135. 35.    
  136. 36.    VERSION=    `$(CAT) VERSION`
  137. 37.    
  138. 38.    # Standard targets
  139. 39.    
  140. 40.    test:
  141. 41.        $(MAKE) "CFLAGS=$(DCFLAGS)" "LIBS=$(DEBUGLIBS)" "LDFLAGS=" $(PROG)
  142. 42.    
  143. 43.    all:        clobber $(PROG)
  144. 44.
  145. 45.    # Build rules
  146. 46.    
  147. 47.    $(PROG):    SCOPTIONS version.o $(OBJS)
  148. 48.        $(CC) version.o $(OBJS) LINK TO $@ BATCH $(LIBS) $(LDFLAGS) $(CFLAGS)
  149. 49.        $(VER) # bump revision for next link
  150. 50.    
  151. 51.    SCOPTIONS:    SMakefile
  152. 52.        $(CP) TO $@ <FROM <
  153. 53.    $(SCOPTIONS)
  154. 54.    <
  155. 55.    
  156. 56.    version.c:
  157. 57.        $(CP) TO $@ <FROM <
  158. 58.    const char VersionID[] = "$$VER: $(PROG) " VERSION " " __AMIGADATE__;
  159. 59.    const char Version[] = VERSION;
  160. 60.    const char CompileDate[] = __AMIGADATE__;
  161. 61.    <
  162. 62.        
  163. 63.    version.o:    version.c $(SRCS)
  164. 64.        $(VER) -n # make sure VERSION exists
  165. 65.        $(CC) NODEBUG DEF=VERSION="$(VERSION)" version.c
  166. 66.    
  167. 67.    rcs:
  168. 68.        ci -l$(VERSION) $(SRCS) $(INCS) $(MISC) $(DOCS)
  169. 69.
  170. 70.    clean:
  171. 71.        $(RM) $(JUNK) $(PROG)_Cat.c >NIL:
  172. 72.    
  173. 73.    clobber:    clean
  174. 74.        $(RM) $(PROG) >NIL:
  175.  
  176.  
  177. Description of the SMakefile
  178.  
  179. In the beginning of the SMakefile are listed the files making up the
  180. project. The name of the program is assigned to the PROG variable, and all
  181. the object, source, and headers files are listed in OBJS, SRCS and INCS,
  182. respectively. MISC is for the other files of the project that should be
  183. archived, including the SMakefile itself. Link libraries used will be
  184. listed in the LIBS variable.
  185.  
  186. The JUNK variable contains the pattern or list of the files that are
  187. created during the build process, and can be deleted to make room.
  188.  
  189. On lines 19-22 are listed the options used in the various build stages.
  190. CFLAGS will be used when compiling the "final" version, while DCFLAGS
  191. holds the options for a "debug" compile. LDFLAGS is the option variable
  192. for the final linking. HOOKFLAGS contains the options needed for callback
  193. hooks (you will not want stack checking on here, even if you'd like it
  194. elsewhere).
  195.  
  196. The options that will be set all the time, regardless of the build mode,
  197. can be saved in SCOPTIONS. The SMakefile will automatically create the
  198. SCOPTIONS file from this variable.
  199.  
  200. Lines 30-34 list the programs used in various stages of the compilation or
  201. project management. By assigning these into variables, there is no need to
  202. repeat the actual program name in the SMakefile, and programs are more
  203. easily changed.
  204.  
  205. The VERSION variable will be set to the current program version during
  206. compilation.
  207.  
  208. Next is the default rule, which simply calls SMake again to build
  209. the project using debug settings. This way you can simply run "smake"
  210. without any options to build a debug version of your binary. Line 42 has
  211. the "all" rule, which is what you would use to create the final binary.
  212.  
  213. The rest of the SMakefile lists the standard rules for the project. These
  214. rules should not change from project to project. The included, larger
  215. SMakefile also includes rules used to create localized source from the
  216. catalog description.
  217.  
  218. The first rule creates the actual binary target file. It will simply link
  219. all the object files together, and if that was successful, bump the
  220. revision number up one so that the next compilation will get a new
  221. version. This is done using a small special utility "ver", source to which
  222. is included.
  223.  
  224. The SCOPTIONS rule recreates the SCOPTIONS file if you change SMakefile.
  225. To rebuild all source files using the new options, add SCOPTIONS to the
  226. dependency list for each source file. This dependency list (as created by
  227. Mkmk, for example) can be appended to the end of the SMakefile, or
  228. inserted anywhere within.
  229.  
  230. The next three rules are for creating the VERSION file that holds the
  231. build number, the version.c source file for the version strings you could
  232. use elsewhere in your program (use the Version[] variable for version
  233. number instead of hardcoding it in other source files), and for compiling
  234. this file.
  235.  
  236. All that is left are the three special rules for archiving the current
  237. source versions and cleaning up the object files are other "junk"
  238. cluttering up the directory. The rcs rule, on line 67, will store all the
  239. source and related files using the build number stored in the VERSION
  240. file. Note that this is one revision higher than the binary created in the
  241. last compilation. This is intentional, since the RCS operation will bump
  242. the timestamps on all the files. You would normally test the program using
  243. the debug version compiled with "smake test" (or simply "smake"), and then
  244. when you are satisfied with the operation, update the documentation etc.
  245. and call "smake rcs". This will store the files and ask you for the log
  246. information for all of them, leaving a modifiable copy of the file
  247. (updated with the new log info) in the directory. You can now call "smake
  248. all" to compile this version, and it will have the same version and
  249. revision as the one archived in the RCS.
  250.  
  251.  
  252.  
  253. This article is Copyright © 1995 Osma Ahvenlampi, <Osma.Ahvenlampi@hut.fi>.
  254. All rights reserved. No part of the article may be copied or distributed
  255. in electronic or printed publications without prior permission of the
  256. author. Permission hereby granted to the Amiga Report Tech Journal.
  257.